package net.shopxx.dao.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.FlushModeType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Repository;

import net.shopxx.constant.AccountsConstant;
import net.shopxx.dao.ShuaDao;
import net.shopxx.dto.TbOrderDTO;
import net.shopxx.entity.ShuaItem;
import net.shopxx.pager.AccountsPageable;
import net.shopxx.pager.Page;

@Repository("shuaDaoImpl")
public class ShuaDaoImpl extends BaseDaoImpl<ShuaItem, Long>implements ShuaDao {

	@Override
	public Long countRecentShuaItem(String userName, String qq, Integer storeId, Date beginDate, Date endDate) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ShuaItem> criteriaQuery = criteriaBuilder.createQuery(ShuaItem.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (userName != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("name"), userName));
		}
		if (qq != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("qq"), qq));
		}
		if (storeId != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), storeId));
		}
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.notEqual(root.get("status"), AccountsConstant.STATUS_SHUADAN_DELETED));
		if (beginDate != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), beginDate));
		}
		if (endDate != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("createDate"), endDate));
		}
		criteriaQuery.where(restrictions);

		return super.count(criteriaQuery, null);
	}

	@Override
	public List<ShuaItem> getInitShuaOrder(TbOrderDTO order) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ShuaItem> criteriaQuery = criteriaBuilder.createQuery(ShuaItem.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(root);

		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("name"), order.getBuyerUserName()));
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), order.getStoreIdByStoreName()));
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.notEqual(root.get("status"), AccountsConstant.STATUS_SHUADAN_DELETED));
		Calendar c = Calendar.getInstance();
		c.add(Calendar.DATE, -29);
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), c.getTime()));

		criteriaQuery.where(restrictions);

		return super.findList(criteriaQuery, null, null, null, null);
	}

	@Override
	public Page<ShuaItem> findStatsPage(AccountsPageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ShuaItem> criteriaQuery = criteriaBuilder.createQuery(ShuaItem.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if (StringUtils.isNotBlank(pageable.getOrderStatus())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), pageable.getOrderStatus()));
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("createDate"), calendar.getTime()));
		}
		criteriaQuery.where(restrictions);

		return findPage(criteriaQuery, pageable);
	}

	@Override
	public Float findStatsSum(AccountsPageable pageable) {

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Float> criteriaQuery = criteriaBuilder.createQuery(Float.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(criteriaBuilder.sum(root.<Float> get("sum")));
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if (StringUtils.isNotBlank(pageable.getOrderStatus())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), pageable.getOrderStatus()));
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("createDate"), calendar.getTime()));
		}
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}
	
	@Override
	public Float findCommissionSum(AccountsPageable pageable) {

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Float> criteriaQuery = criteriaBuilder.createQuery(Float.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(criteriaBuilder.sum(root.<Float> get("commission")));
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if (StringUtils.isNotBlank(pageable.getOrderStatus())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), pageable.getOrderStatus()));
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("createDate"), calendar.getTime()));
		}
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}

	@Override
	public Long findStatsCount(AccountsPageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ShuaItem> criteriaQuery = criteriaBuilder.createQuery(ShuaItem.class);
		Root<ShuaItem> root = criteriaQuery.from(ShuaItem.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		if (StringUtils.isNotBlank(pageable.getStoreId())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("storeId"), pageable.getStoreId()));
		}
		if (StringUtils.isNotBlank(pageable.getOrderStatus())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("status"), pageable.getOrderStatus()));
		}
		if (StringUtils.isNotBlank(pageable.getOperator())) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("operator"), pageable.getOperator()));
		}
		if (pageable.getBeginDate() != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date> get("createDate"), pageable.getBeginDate()));
		}
		if (pageable.getEndDate() != null) {

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(pageable.getEndDate());
			calendar.add(Calendar.DAY_OF_MONTH, 1);
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("createDate"), calendar.getTime()));
		}
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}
}
